Skip to main content
Version: 7.8

Development Best Practices

Naming Convention Recommendations

Naming conventions should be based on an organizing principle, and are constrained by the technology in which they are applied. Organizing principles must consider the benefits and business value of conventions.

Potential Benefits

Some of the potential benefits that can be obtained by adopting a naming convention are:

  • Provide additional information about the use to which the object referred to by an identifier is put.
  • Formalize expectations and promote consistency within a development team.
  • Enable the use of automated search, refactoring, and replace tools with minimal potential for error.
  • Enhance clarity in cases of potential ambiguity (use of modules and namespaces).
  • Enhance the aesthetic and professional appearance of work product (for example, by disallowing overly long names, comical or "cute" names, or abbreviations).
  • Avoid "naming collisions" that might occur when the work products of different organizations, individuals or groups are combined.
  • Provide meaningful data to be used in project handovers (such as promotion from development to production) which require submission of tasks, runbooks, documents, and other artifacts as well as relevant documentation.
  • Provide better when objects are used in multiple solutions (such as using ActionTasks in a Runbook).
  • Provide better understanding in case of reuse after a long interval of time.

Business value

Appropriately chosen identifiers make it easier for subsequent analysts and developers to understand what the system is doing and how to fix or scale it for new business needs.

Naming in Resolve Actions Pro

Document names (as well as Runbook and Decision Tree names which use documents as containers) consist of two parts: a namespace and a name that are separated by a dot or period.

The namespace provides a mechanism for grouping related documents (most used and useful purpose) and is a means to have two documents with the same name representing different domains (less useful and used). The combination of namespace and name must be unique.

Namespaces can be used as a convenient means for "exporting" groups of documents for copying to another environment as in a handover from development to production. 

ActionTasks are grouped into modules which serve a similar purpose to namespaces. In addition ActionTasks can be associated with "menus" allowing for alternate organization. The major theme for organization of ActionTasks is the ability to quickly locate them when used in a Runbook. Another area for conventions is the naming of variables and properties. The name should appear such that they can be quickly found when used in code. For that reason the form as well as the actual name is important. The following are practices for naming. They should be adapted by each enterprise to their local needs.

General Considerations

Names in Actions Pro are case-sensitive.

  • If a name is created in mixed case, then it will appear as such when displayed.
  • Searches ignore case.
  • Names varying by only the case of the letters will not be treated as different in Actions Pro (due to the search element). For instance documents name "ns.doca" and "ns.DOCA" should be considered the same document. This rule applies to all object naming in Actions Pro. In many cases underscores can be used as part of a name. They should be avoided due to their role as a wildcard character in searches.
note

This caveat can change in future Actions Pro releases.

Document Page Naming

Wiki document page names are used by all users to locate a particular page and should support recognition and search. Names are in two parts: a namespace and a name. Each combination of a namespace and name must be unique.

Namespace

Namespaces are:

  • single level
  • lower case
  • may contain blanks, underscores, dashes

They allow grouping of pages for multiple purposes. Typical organizing considerations are project, subject matter area or organization depending on the predominant need.

Wiki Name

Wiki document page (Runbook, Decision Tree, and Document) names can only include alphanumeric values, blanks, underscores, and dashes. Wiki names are case sensitive.

  • Capitalization can be used to delineate parts of a name.
  • Hyphens ("-") and blanks are allowed and can be used for segmenting a name.
  • A method of delineation should be chosen and adhered to.
  • Names should not contain underscores to delineate parts of the name. For example, if you are working on a customer support representative project (csr) on a customer search page, a wiki page name could be "csr.customer search" or "csr.CustomerSearch".

Summary in Document Properties

The Summary for a wiki page is accessed while editing in the Properties tab screen. This summary is defaulted to a portion of code from the start of the page. It is displayed in the Document list in the Wiki Administration menu. Summaries can make locating a document under Wiki Administration search easier. These should be edited with a meaningful description added. The Summary is limited to 4,000 characters but should be kept short to fit into the listing.

ActionTask Naming

Two guiding principles for ActionTask naming:

  • Names should facilitate use
  • Names should make functions easily recognizable

ActionTask names consist of two parts; a module (namespace) and the name. When setting up standards or conventions for naming, care should be taken to avoid replication of parts of the name in each part (for instance, if a module name is established that identifies ActionTasks as Cisco related, then the subordinate Action Task names should not have Cisco as part of them). Each module and name pair must be unique.

Namespace

The module is generally used during administrative types of activities, such as Import/Export. It should be organized to facilitate finding ActionTasks when performing these types of activities. Many administrative activities are oriented around areas of responsibility and a naming convention should be based around those areas. Different module names can be applied to each component part of an ActionTask (Preprocessor, Parser, and Assessor) as well as the ActionTask itself.

  • It is a recommended practice that when not developing a component for re-use, the module name for each component should be the same as the Action Task.
  • Module names should be all lower case and are multilevel, with levels in the name delineated by periods (dots).

One convention for module naming is: <owner>.<functional area>.<qualifiers> where:

  • Owner is the organization, a local enterprise name or external company name, that delivered the ActionTask component. For example, ActionTasks delivered by Actions Pro Systems have owner as "resolve".
  • Functional area refers to the segment of Operations that is the target for the ActionTask. If the ActionTask is generic to all areas the term "general" might be used. If the ActionTask is network operations based then "network" might be used. For a system operations based ActionTask, the term "system" could apply and so on.
  • Qualifiers give a more granular indication of the area of an ActionTask and are optional. For instance, a sub grouping of network related ActionTasks could be by vendor ("cisco", "juniper", etc.). Further delineation based on interest of the Administrators, such as type of device, or type of action (data gathering, triage, etc.) could be added. Each added level should be based on the needs of administrative activities.

Example:

  • resolve.network.triage.cisco
  • resolve.system.diagnose
  • myenterprise.storage.san

Name

ActionTask names should be all lower cases and provide some idea as to the function within the module space, for example, "ssh connection", "telnet connection", "database access", and so on. A fully qualified ActionTask name can become long. An example of a full name is myenterprise.network.triage.cisco.router.2200.ssh connect. The italicized portion is the module and the bold portion is the ActionTask name.

The menu path is mainly used by developers during maintenance of the ActionTasks and when selecting them for use in a Runbook. Menu should be broken up into functional components, with the first level being the major function and each sublevel further dividing into functional areas. Care must be taken not to be too granular and make the path very long and the number of entries in the lowest level too few. ActionTasks can be positioned at all levels in the menu hierarchy, not only at the lowest.

Examples of menu paths for a system service and network service:

  • /network/service/cisco/configure – Configuring a Cisco device
  • /network/service/cisco/deploy – Deploying a new Cisco device
  • /network/service/juniper/remove – Removing (decommissioning) a Juniper device
  • /system/service/util – Utility Action Tasks for system management services
  • /system/service/db – Generic database services
  • /system/service/db/maint – Database maintenance
  • /system/service/db/security – Database security configuration (such as access requests)

Other ActionTask Elements

Other elements related to an ActionTask provide further documentation and clarity. These elements can be found on the General tab when editing an ActionTask. Recommended practices include:

  • Summary - All ActionTasks should have a summary description. Summaries are limited to 100 characters or less and appear in the ActionTask lists.
  • Description – A description further clarifying the purpose of an ActionTask and other requirements or restrictions for its use should be included. The Description appears in the "mouse-over" information in the Model Builder interface.
  • PARAMS tab – Inputs and Outputs defined on the PARAMS tab in the ActionTask editor should contain a description. It will appear in the "mouse-over" information in the Model Builder interface.

Tags

Tags can be applied to many of the objects in Actions Pro (such as ActionTasks and Wiki pages), and enhance the ability to locate object in Actions Pro. A "tag space directory" listing tags and their meaning should be maintained within an enterprise to help developers and administrators in selecting which to apply. Tags can be multi-level using a period (dot) to delineate levels. Actions Pro searches allow searching by one or more tags. The recommended practices for tag use are:

  • Tags should be all lowercase
  • Multiple tags may be associated with an Actions Pro object such as a wiki page or ActionTask
  • At minimum, one tag should be created for each associated with an object
  • Consider using a tag for each portion of a multi-part namespace or module and apply them to all components in that namespace or module to facilitate easier searches

Properties Naming

Properties are used to hold data values that are available throughout the Actions Pro system for ActionTasks and Runbooks. They are grouped into modules to make administration easier.

Name

Property names can be mixed case, but the recommended practice is for names to be all upper case. For a multi-part name, an underscore (_) can be used to separate the parts. Property names should reflect the content of the Property; for instance NETCOOL_DB_SERVER.

Namespace

Namespaces are mainly used for Administrative functions, such as Import/Export. The considerations for namespace naming are the same as those for ActionTasks.

  • Users with WRITE permissions to a Namespace are able to create and modify Action Task Properties in it.
  • Users without WRITE permissions to a Namespace are not able to edit existing Action Task Properties in that Namespace or create new Properties in it.
  • Users with READ permissions to a Namespace are able to view the Action Task Properties in it and include them in Automations/Action Tasks while building those.
  • Users without READ permissions to a Namespace are not able to view the Action Task Properties in it and cannot include them in Automations/Action Tasks while building those.
  • Users with EXECUTE permissions to a Namespace are able to execute Runbooks that have Action Task Properties form that Namespace .
  • Users without EXECUTE permissions to a Namespace are not able to execute Runbooks that have Action Task Properties form that Namespace .

Variable Naming

INPUTS, OUTPUTS, FLOWS, and PARAMS are the forms of variables supported in Actions Pro. Each variable name represents a name field in a hash. 

The recommended practice is to use all UPPERCASE for variable names, with an underscore (_) separating each part of a multi-part name. Names should be indicative of the content of the variables. Examples of variables names are IP_ADDRESS or SECOND_SCREEN_VALUE. ActionTask internal variables are those created and used within a Groovy script. For these, normal considerations for good programming practices should be followed. These variable names are case sensitive ("myVar" is not the same variable as "MYVar") and can have no embedded spaces.

Custom Table Naming

Custom Table names should be all the same case (preferably lowercase) with multi-part names delimited with an underscore. The name should reflect the use and content of the table, with the first part of the name represent the use or project and the second part indicating the content.

Export Package Naming

Export packages provide a means to copy Actions Pro items to an external file, which can be moved to another Actions Pro system for import or kept as a backup. Export packages are related to "projects" and can contain all of the objects require to instantiate a solution (Runbooks, Decision Trees, Documents, ActionTasks, Properties, Tags, etc.). Export packages can also be used for backup of critical Actions Pro components when changes are being made, allowing for quick recovery (Properties for example).

It is a recommended practice to keep export module names all lower case. Naming of export packages should relate to the purpose of the export (typically a solution name) and then externally be modified to reflect a version. To do this, create a general export and add version information after downloading a file version of the export (a zip file) to a local server. For example, create the definition, export, and download a module called csr_backup.zip. After export, add the date and other info to the extension. Text after the .zip extension will not be seen by Actions Pro.

  1. Create an export and download, for instance csr_[NAME].zip.
  2. Add version information after zip file extension, for example, csr_[NAME].zip.[DATE]_[VERSION].
  3. The csr_backup.zip.20131030_d1 might represent making back up of csr name space with time stamp.
    A practice can be developed to use exports for to save cross solution and non-solution related components such as:
  4. Properties.
  5. User/group/roles.
  6. Custom Table/Form definitions.

Naming for the non-solution component export modules should refer to the component, date of export and any other scoping. Here are two examples:

  • properties_03sep2013_all.zip
  • properties_03sep2013_csr.zip

Groovy Scripts in ActionTask Content

An ActionTask executes script code from its Content component. In a REMOTE-type task, Groovy code is placed in the Content section and this is executed by the RSRemote (in an OS-type task. The shell command from the Command Line section is sent and executed by the RSRemote). See ActionTask Components for command line details.

Although other scripting languages can be used, Actions Pro runs Groovy natively.

  • The Content can contain most Groovy language elements and libraries (including Java).
  • The Content script code is sent to the RSRemote as a temp file, which is then run through the Groovy interpreter.
  • The name of the temp file can be accessed via ${INPUTFILE}. For example, in a Groovy script, this:
def input File Name = "${INPUTFILE}"
Becomes something similar to this:
def input File Name = "infile_pool_3_thread_3.in"
  • The results of the Groovy script, passed back via "return" values, are passed as a RAW variable to the Parser and Assessor (see the process execution flow in Action Task Development; Action Task Components).
  • The "return" values, however, must be either of class String or convertible to String.
    • This is a known limitation of Actions Pro (related to interaction with message queuing), and not Groovy.
    • A library exists, extending the StringUtils class that converts objects to Strings. The Actions Pro implementation of StringUtils extends the Apache. The method to use is:
public static String obj ToString(Object obj)

To convert an object to String(ByteArray):

String s StringUtils.objToString(Object your Object)

Then, when you need to restore it, use string To Obj(String):

Object your Object = StringUtils.stringToObj(String s)

ActionTask Assessor Guidelines

Here are some guidelines to follow:

  1. Avoid using FLOWS (or GLOBALS) in Assessors whenever possible
    • Use OUTPUTS in Assessors
    • Configure Runbooks to copy OUTPUTS to FLOWS
  2. Avoid using "sleep" commands in Assessors
    • It holds onto a DB connection for seconds, which is a long time
    • Use Thread.sleep() in Content screen instead
  3. Use RESULT.condition to denote if the task succeeded or failed; it is used by the automation model.
  4. Use DEBUG.println() in Debug mode to output to the Worksheet Debug tab; also use DEBUG.printInputs() and DEBUG.printOutputs().
  5. The Actions Pro database can be used by the DB object (java.sql.Connection) Use LOG.error() to output to the rscontrol.log file; you can also use LOG.warning(), LOG.debug(), and so on.
  6. Simple string manipulation are preferred, such as index Of(); Use regex only when needed.
  7. Assessors can call other assessors; def obj = ASSESS.execute(<assessor name>,<args object>).

Runbooks can be launched from an Assess script Worksheet fields can be set using the WORKSHEET object in the Assessor:

  • The fields are set using the database fields
  • Usually u_fieldname lower case
  • Example: WORKSHEET.u condition = "good" sets the Worksheet condition to good
  • WORKSHEET is a write-only object
  • Cannot be used to get values from the current WORKSHEET

Other Groovy Script Guidelines

Keep in mind the different ActionTask components and their respective functions and locations (Actions Pro components). Keep the Content scripting simple and clear and avoid using "business logic". Save the business logic or assessment for the Assessor.

  • Use try/catch blocks to handle exceptions. The default handling returns error (output) in the RAW variable to the next ActionTask component.
  • To insert a delay in a task, use Thread.sleep() and avoid the Groovy sleep() command.
  • Avoid regular expressions and use simple string manipulation, such as indexOf(), toString(), and substring().

Debugging ActionTasks

Potential problems with ActionTasks come in three general categories:

(1) errors during execution
(2) task does not run (stays in open queue)
(3) task runs, but unexpected results occur.
There are general troubleshooting guidelines to follow, as well as helpful parameters (the LOG variable) to use in debugging ActionTasks.

Testing and Troubleshooting Guidelines

ActionTasks should be tested independently from other tasks, if possible. Use direct execution from the editor toolbar (via the "Play" icon  ) and try all variations of input values. The Mock options are helpful for this purpose. As with programming, use logging to trace the code (see below) and add more information to the output (for Content, add to RAW; for the Assessor, add to DETAIL).

Programming Practices for Actions Pro

Following best practices in programming for Runbook development can simplify troubleshooting and maintenance as well as improve performance. An enterprise should evaluate their current programming practices from other areas (such as code structure and variable naming standards) to adapt for use when coding Groovy and other scripts in Actions Pro.

Input and Output Parameters

Do not use the literal substitution form of INPUTS ($INPUT{<name>}) in the Content of a Remote Action Task. Though the substitution and code execute, this usage causes a form of memory leak that compromises performance and reliability.

  • To improve reusability, troubleshooting, and Runbook maintenance, ActionTasks should use only INPUTS and OUTPUTS, and avoid FLOWS, PARAMS, and WSDATA.  INPUTS can have their values assigned to other variable types in the Runbook "Edit Inputs" settings. OUTPUTS can be assigned to FLOWS, PARAMS, and WSDATA in the "Edit Outputs" settings in a Runbook.
  • Do not use PARAMS as the default values for the INPUT parameter in an ActionTask definition. This sets the INPUT to the value of the PARAM at the start of the Runbook and not to the value at the point of execution. This complicates troubleshooting.
  • Use GLOBALS only when values must be saved when using targets or on merged paths. Global variable names on each merged path or for each target must be unique to be retained after merging.
  • Use $PROPERTY{<XXX>} in the "Default Value" to set ActionTask property values to an INPUT.
  • Use only $PROPERTY{} and constant values for default values in the ActionTask definition and use the Automation Model to set FLOWS, PARAMS, or WSDATA values.

General

Here are some guidelines to follow when using Actions Pro Runbook:

  • All variables in Groovy scripts should be defined using the "def" keyword. This localizes the scope and helps prevent inadvertent value changes.
  • Avoid using regex in Groovy scripts if simple string manipulation, such as indexOf() or substring(), is enough. This helps to improve performance.
  • Two methods for outputting debug and trace information are available to improve troubleshooting.
  • Use LOG.<level>() to output to log files. The levels to use from most to least verbose are: DEBUG, INFO, WARN, and ERROR. The setting in each Actions Pro component log configuration determines the highest logging level and applies to all Action Tasks (and Runbooks).
  • The default level for production Actions Pro installations should be set to WARN. If troubleshooting requires, raise the level for the time required, then return it to the default level. This can be accomplished using RSCONSOLE.
  • Use DEBUG.println() to output to the Worksheet debug tab. This only applies to Action Tasks and Runbooks running in DEBUG mode.
  • Keep log messages as concise as possible.
  • When creating messages for either logging method, use a common format which should include a unique identifier to easily locate these special messages in the log output. This also helps to keep log messages brief. For instance, use a string such as <enterprise> <level> <message number> <message> in which:
  • "enterprise" is a unique key identifying the message as local to a specific company
  • "level" indicates severity or purpose of the message
  • "message" number uniquely identifies the message and should be documented in a message catalog
  • "message" is the specific text giving more detail

Runbook Deployment

Here are some guidelines to follow when using Runbook Deployment:

  • Single Runbook: use single standalone Runbooks or pre-existing sub-Runbooks for small- to medium-sized automations
  • Called Runbooks: take advantage of multi-threading in parallel execution
  • Embedded Runbooks using subprocesses (sub-Runbooks): use sub-Runbooks for medium- to large-size automations and exploit reusable components (commonly-used Runbooks)

Sub-Runbook Recommendations

  • Sub-Runbooks (sub processes) let developers organize and reuse logic .
  • Consider modularity in designing solutions
  • Data handling is a big concern with sub-Runbooks
  • An approach is to use a task before the sub-Runbook to marshal the data and validate the inputs
  • Choose the data types based on purpose
  • Use PARAMS for stand-alone sub-Runbooks
  • Use FLOWS for sub-Runbooks that are always embedded

Concurrent Runbook Recommendations

  • Having a large number of targets in a parallel Runbook may cause the Runbook to time out and abort if there are too many tasks finishing roughly at the same time. One way to prevent this is to limit the number of TARGETS being created in a task. More specifically, you can loop through the parallel section and only do a limited count of concurrent targets at a time. The system’s maximum throughput depends on your hardware. As a rule of thumb, keep the number of parallel tasks in the lower hundreds.

Sub-Runbook Usage Example

The following diagram shows a sample use of sub-runbooks:

ActionTask Content (Tab)

Here are some guidelines to follow when using ActionTask Content:

  • Avoid business logic (success/failure evaluation) in the Content; assess the business logic in the Assessor. Keep it simple and clear.
  • Never use the sleep() method. If a delay is required, use the Thread.sleep() method in the Content (and not in the Assessor, see below).
  • Improve performance by limiting the amount of data stored in FLOWS. Limit the use of FLOWS to where they are needed and remove FLOWS entries that are no longer needed.
  • Content can be a Groovy Script for a REMOTE-type ActionTask. For other ActionTask types, except ASSESS (OS, BASH, CMD), it will act as a temporary file, and can be referenced using ${INPUTFILE}. For non-groovy code, use $INPUT{<XXX>} to do a literal string substitution to pass parameters into the script/file content.
  • The substitution of the value for the variable is done before creating the ${INPUTFILE}.
  • Use quotes around $INPUT since the value is substituted rather than acting like a variable. Watch out for newlines in the string. See the shell script example below:
// exception when XXX has a \n character in it  
var mystring = "$INPUT{XXX}"
  • Use try/catch blocks to handle the exceptions in code sections. Groovy errors in Content in a REMOTE-type ActionTask will still be caught and returned in the RAW variable, which may also be displayed to the user in the Detail.
  • The return value from the Content groovy script will be converted to a String value. Use INPUTS to pass structured values to the Assessor from Content. For example, INPUTS"MYMAP" = 'my key':' my value' will pass the map from the Content to the Assessor.
  • Use SESSIONS to re-use connections allowing multiple commands for a given target system to be executed and assessed in separate ActionTasks. This provides better maintainability and troubleshooting. It can lead to better performance overall. Use of the SESSIONS object causes the Runbook ActionTasks that follow to be executed on the same RSRemote. When using SESSIONS remember:
  • Close the connection at the end of its use.
  • Remove the SESSIONS object entry at end of use to remove the affinity setting for a particular RSRemote.
  • Tasks that use SESSIONS can only be run as part of a Runbook.
  • GLOBALS, WSDATA, and OUTPUTS cannot be used in Content Tab. Use INPUTS for most operations when needed.
  • Code related to gateways and connectors must be run from the Content of a REMOTE-type ActionTask.

ActionTask Assessor

Here are some guidelines to follow:

  • Each ActionTask should have their own Assessor.

  • Avoid using Reference (shared) Assessors unless it makes sense to share the Assessor.

  • The major role of the Assessor is to set the RESULT object values. Structuring code to set defaults, perform logical assessment, changing values, and then moving values to the RESULT object simplifies maintenance. The following is an illustrative example:

    <span style="color: #808080">// Set default RESULT variables</span>
    def condition <span style="color: #484848">=</span> <span style="color: #5d90cd">"GOOD"</span>;
    def severity <span style="color: #484848">=</span> <span style="color: #5d90cd">"GOOD"</span>;
    def summary <span style="color: #484848">=</span> <span style="color: #5d90cd">"The uptime is "</span>;
    def detail <span style="color: #484848">=</span> <span style="color: #5d90cd">"The original uptime was</span> <span style="color: #5d90cd">$RAW\n"</span>;

    <span style="color: #808080">// Set other work variables</span>
    def seconds up <span style="color: #484848">=</span> RAW.split()\[<span style="color: #46a609">0</span>\].toDouble();
    def hoursup <span style="color: #484848">=</span> (seconds up / <span style="color: #46a609">3600</span>).round(<span style="color: #46a609">2</span>);

    <span style="color: #808080">// Perform assessment logic</span>
    summary <span style="color: #484848">+=</span> hoursup;
    detail <span style="color: #484848">+=</span> <span style="color: #5d90cd">"The uptime in hours is $hoursup"</span>;

    <span style="color: #808080">// Set values in the RESULT object</span>
    RESULT.summary <span style="color: #484848">=</span> summary;
    RESULT.condition <span style="color: #484848">=</span> condition;
    RESULT .severity <span style="color: #484848">=</span> severity;
    RESULT.detail <span style="color: #484848">=</span> detail;

    <span style="color: #808080">// Set other variables</span>
    OUTPUTS\[<span style="color: #5d90cd">'UPTIME'</span>\] <span style="color: #484848">=</span> hoursup
  • Use the hash map version of variables (such as INPUTSXXX?, PARAMSXXX?) and not the literal substitution version (such as $INPUT{).

  • Avoiding directly setting FLOWS in an Assessor. Use OUTPUTS and configure the Runbook to copy the OUTPUTS to FLOWS.

  • Avoid using Thread.sleep() in Assessors due to holds on to DB connections. Use Thread.sleep() in Content instead. Never use the Groovy sleep() method.

  • Use DEBUG.println() to output to the Worksheet debug tab.

  • Also try DEBUG.printInputs() or DEBUG.printOutputs().

  • A connection to the Actions Pro database can be made using the DB object (java.sql.Connection) and standard JDBC methods. This should only be used for read-only access, never to add or update data. This is due to the persistence mechanism. Current Worksheet data cannot be accessed through the Actions Pro database and must come from RSSearch. Use the data API for access to table information in the Actions Pro database (including custom tables). entity Util provides the mechanism for Worksheet access.

ActionTask Preprocessor

Here are some guidelines to follow:

  • INPUTS can be set from PARAMS in the Preprocessor, however, this should only be done when there are logical decisions or complex manipulations to be done. Simple replacement should be done in the "Edit Inputs" of a Runbook definition.
  • Preprocess can set TARGETS to allow parallel execution.
  • Only PARAMS are sent to the targets for the remaining ActionTask logic, not INPUTS.
  • Whenever possible, use either the default QUEUE_NAME (RSRemote) or set the QUEUE_NAME in Options, instead of placing queue_name in TARGETS.
  • When used in a Runbook, consider setting TARGETS and only manipulating variables in an ASSESS-type ActionTask, deferring logic to later ActionTasks. PARAMS from the targets can be assed to OUTPUTS and used subsequently in the Runbook. This will simplify maintenance and troubleshooting.
  • Create a local Preprocessor for an ActionTask, avoiding Reference (shared) Preprocessors.

ActionTask Parser

Parsers allow converting from one format of data returned from the RSRemote (RAW) to a form of data more suited to use by an Assessor (DATA).

User Interface Guidelines

Use Document sections to simplify maintenance. Standard components such as headers, footers, pro forma notices, CSS, and other aspects of a user interface should be included (typically by section) from a single source document.

Groovy Console

External tools can be used to help with testing and troubleshooting. Groovy Console can be used to test and develop logic, although the release versions of Groovy Console and the Actions Pro Groovy code (dependent on the Actions Pro release) should be considered. Something that runs in the newest Groovy Console may not be supported in the Actions Pro Groovy version. Release notes should be referenced. The documentation at the Groovy support site does a fair job of showing what features are new to a release. If code works in Groovy Console and not in Actions Pro, suspect a release issue.

Coding using "cut-and-paste" editing can also add hidden characters to code and cause Groovy errors. If in question, re-type rather than insert code and see if the problem goes away (or moves to the next line).

Debug Mode

Debug information can be built into the Groovy code of a REMOTE-type Action Task and displayed when the task is executed in "Debug" mode. DEBUG statements (DEBUG.println) and log output from the task execution are shown on the "Debug" tab of the worksheet. Debug statements only get printed when an ActionTask is running in Debug mode.

To enable debug mode, ensure that the Debug box is checked when executing an ActionTask.

Using an identity field in the DEBUG.println makes the string message easier to trace. For example, start the string with "EXAMPLE: ..." to make the message stand out:

DEBUG.println("EXAMPLE: Step x of process complete");

Task Not Running

If an ActionTask is not running, then the task status will remain "open" in the request history. There are a few questions to check:

  • Is an RSRemote running?
  • Is the QUEUE_NAME set to a non-existing queue or a queue with no running RSRemote?
  • Has the TARGET been set to a non-existing queue or a queue with no running RSRemote?
  • Is the task doing work, but running a long time or waiting for a resource to be freed?

Unexpected Results

If an ActionTask returns unexpected results, then check the task using logging to trace the execution.

  • If a Parser is used, check that the Parser and Assessor have matching data types
  • Check the TARGET: in looking for where a task runs, you may need to check multiple RSRemotes if more than one is listening on a QUEUE
  • If the task assumes a Windows target, is it running on a Windows-based RSRemote?
  • Consider adding TARGET to the task RAW output
  • Check the log file on the RSRemote that should be running the task

The LOG Variable and Logging Guidelines

The LOG variable is a helpful debugging parameter that is used to output messages to log files.

  • The ActionTask component location of the LOG object determines the log file destination of the message.
  • LOG messages placed in a Preprocessor or Assessor appear in the log for RSControl (where the Preprocessor and Assessor are), while LOG messages put in a REMOTE-type ActionTask INPUTFILE appear in the RSRemote log.
  • Note that the LOG object is only available in Groovy scripts (Preprocessor, Assessor, and REMOTE-type task INPUTFILE).
  • In an HA environment, the LOG message displays in the log file of whichever component ran the script, so searching multiple logs may be required.

The general logging syntax is LOG.("some message"); where is error, warn, info, or debug:

LOG.error("Error message");  
LOG.warn("Warning message");
LOG.info("Information message");
LOG.debug("Debug message");

Follow these guidelines:

  • Logging messages; avoid using a generic "some message" that can be difficult to distinguish; use a unique signature that is easy to identify.
  • Use a consistent format for messages to facilitate finding messages in logs and that indicate the source and severity of the message. A preferred pattern to follow might be:
"<level>_<task name>_<message id>: message"

with "message id" as a unique string assigned to the message.

Configuring Log Files

Logging in Actions Pro uses log4j. The log4j configuration file can be found at <actions-pro-home>/RSRemote/config/log.cfg for an RSRemote. A sample config file might look like this:

rsremote.log4j.Loggers.Root.level=WARN
rsremote.log4j.Loggers.Root.appender-ref.ref=RSREMOTE,amqp
rsremote.log4j.Loggers.Logger.com.resolve.rsremote.level=${rsremote.log4j.loglevel}
rsremote.log4j.Loggers.Logger.com.resolve.dcs.httplogappender.level=INFO
rsremote.log4j.Loggers.Logger.DCS.level=INFO
rsremote.log4j.Loggers.Logger.DCS.appender-ref.ref=DCS
rsremote.log4j.Loggers.Logger.syslog.level=ERROR
rsremote.log4j.Loggers.Logger.syslog.additivity=false
rsremote.log4j.Appenders.RollingFile.name=RSREMOTE
rsremote.log4j.Appenders.RollingFile.fileName=rsremote/log/rsremote.log
rsremote.log4j.Appenders.RollingFile.filePattern=rsremote/log/$\\${date:yyyy-MM}/rsremote-%d{MM-dd-yyyy}-%i.log.zip
rsremote.log4j.Appenders.RollingFile.PatternLayout.pattern=%d{ISO8601}{GMT+0} %5p [%t] (%F:%L) - %m%n
rsremote.log4j.Appenders.RollingFile.SizeBasedTriggeringPolicy.size=32MB
rsremote.log4j.Appenders.RollingFile.DefaultRolloverStrategy.max=6
rsremote.log4j.Appenders.AmqpAppender.name=amqp
rsremote.log4j.Appenders.AmqpAppender.threshold=WARN
rsremote.log4j.Appenders.AmqpAppender.PatternLayout.pattern=%d{ISO8601}{GMT+0} %5p [%t] %X{context} %X{filter} (%F:%L) - %m%n
rsremote.log4j.Appenders.HttpLogAppender.name=DCS
rsremote.log4j.Appenders.HttpLogAppender.charset=utf-8
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationInstance=update-me
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationUsername=update-me
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationPassword=update-me
rsremote.log4j.Appenders.HttpLogAppender.hostAddresses=${RSREMOTE_RSDATALOADER_URL}
rsremote.log4j.Appenders.HttpLogAppender.httpConnectionTimeout=5000
rsremote.log4j.Appenders.HttpLogAppender.httpSOTimeout=1000
rsremote.log4j.Appenders.HttpLogAppender.maxConnections=100
rsremote.log4j.Appenders.HttpLogAppender.templatesToEndpointsMapping=data-collector-template:/api/v1/data/collected,incident-events-template:/api/v1/data/incident/events
rsremote.log4j.Appenders.HttpLogAppender.threadCount=10
rsremote.log4j.Appenders.HttpLogAppender.PatternLayout.pattern=%m
rsremote.log4j.Appenders.HttpLogAppender.enabled=false
rsremote.log4j.Appenders.HttpLogAppender.sslEnabled=${RSREMOTE_SSL_ENABLED}
rsremote.log4j.Appenders.HttpLogAppender.sslVerify=${RSREMOTE_SSL_VERIFY}
rsremote.log4j.Appenders.HttpLogAppender.trustStore=${RSREMOTE_TRUSTSTORE_PATH}
rsremote.log4j.Appenders.HttpLogAppender.trustStorePassword=${RSREMOTE_TRUSTSTORE_PASSWORD}
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationInstance=${RSREMOTE_RSDATALOADER_URL}/login
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationUsername=rsremote
rsremote.log4j.Appenders.HttpLogAppender.dcsAuthenticationPassword=Resolve1

The level setting for a log file is set by the .log4j.Loggers.Root.level command. It gives the lowest level of messages from DEBUG, INFO, WARN to  ERROR . The log file prints only messages of the set level and higher, therefore the DEBUG setting logs all messages, while the ERROR setting logs the least. The logging level can be changed dynamically. The default level is WARN: .Logging at the DEBUG level is quite a lot for robust Runbooks, and might even compromise performance.

The log file location is set by the   .log4j.Appenders.RollingFile.fileName command.

Similar Log4j settings exist at:

  • <actions-pro-home>/RSControl/config/log.cfg for the RSControl log4j configuration
  • <actions-pro-home>/rsarchive/config/log.cfg for the RSArchivel log4j configuration
  • <actions-pro-home>/rosconsole/config/log.cfg for the R Console log4j configuration
  • <actions-pro-home>/rsmgmt/config/log.cfg for the RSMgmt log4j configuration
  • <actions-pro-home>/rssync/config/log.cfg for the RSSync log4j configuration

The log file locations should be isolated away from the root file system to avoid filling it with log files.
For detailed information about Log4j Blueprint properties configuration, refer to Blueprint Configuration.